﻿Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Globalization
Imports System.Runtime.CompilerServices
Imports System.Windows.Forms
Imports System.Workflow.ComponentModel

Namespace System.Workflow.ComponentModel.Design
    Friend NotInheritable Class PreviewWindow
        ' Events
        Public Custom Event PreviewModeChanged As EventHandler

        ' Methods
        Public Sub New(ByVal parent As ActivityPreviewDesigner)
            Me.parentDesigner = parent
            Me.serviceProvider = Me.parentDesigner.Activity.Site
        End Sub

        Public Sub Draw(ByVal graphics As Graphics, ByVal viewPort As Rectangle)
            Dim designerTheme As ActivityPreviewDesignerTheme = [TryCast](Me.parentDesigner.DesignerTheme,ActivityPreviewDesignerTheme)
            If (Not designerTheme Is Nothing) Then
                Dim margin As Size = WorkflowTheme.CurrentTheme.AmbientTheme.Margin
                ActivityDesignerPaint.DrawText(graphics, designerTheme.Font, Me.PreviewModeDescription, Me.previewModeDescRectangle, StringAlignment.Center, WorkflowTheme.CurrentTheme.AmbientTheme.TextQuality, designerTheme.ForegroundBrush)
                graphics.DrawRectangle(Pens.Black, CInt((Me.previewModeButtonRectangle.Left - 1)), CInt((Me.previewModeButtonRectangle.Top - 1)), CInt((Me.previewModeButtonRectangle.Width + 1)), CInt((Me.previewModeButtonRectangle.Height + 1)))
                ActivityDesignerPaint.Draw3DButton(graphics, Nothing, Me.previewModeButtonRectangle, 1!, If(Not Me.PreviewMode, ButtonState.Pushed, ButtonState.Normal))
                Dim image As Image = If(Me.PreviewMode, ActivityPreviewDesignerTheme.PreviewButtonImage, ActivityPreviewDesignerTheme.EditButtonImage)
                ActivityDesignerPaint.DrawImage(graphics, image, New Rectangle((Me.previewModeButtonRectangle.Left + 2), (Me.previewModeButtonRectangle.Top + 2), (Me.previewModeButtonRectangle.Width - 4), (Me.previewModeButtonRectangle.Height - 4)), DesignerContentAlignment.Center)
                graphics.FillRectangle(designerTheme.PreviewBackgroundBrush, Me.canvasBounds)
                If Me.PreviewMode Then
                    graphics.DrawRectangle(designerTheme.PreviewBorderPen, Me.canvasBounds)
                Else
                    Dim canvasBounds As Rectangle = Me.canvasBounds
                    canvasBounds.Inflate(2, 2)
                    graphics.DrawRectangle(SystemPens.ControlDark, canvasBounds)
                    canvasBounds.Inflate(-1, -1)
                    graphics.DrawLine(SystemPens.ControlDarkDark, canvasBounds.Left, canvasBounds.Top, canvasBounds.Left, canvasBounds.Bottom)
                    graphics.DrawLine(SystemPens.ControlDarkDark, canvasBounds.Left, canvasBounds.Top, canvasBounds.Right, canvasBounds.Top)
                    graphics.DrawLine(SystemPens.ControlLight, canvasBounds.Right, canvasBounds.Top, canvasBounds.Right, canvasBounds.Bottom)
                    graphics.DrawLine(SystemPens.ControlLight, canvasBounds.Left, canvasBounds.Bottom, canvasBounds.Right, canvasBounds.Bottom)
                    canvasBounds.Inflate(-1, -1)
                    graphics.DrawLine(SystemPens.ControlLight, canvasBounds.Left, canvasBounds.Top, canvasBounds.Left, canvasBounds.Bottom)
                    graphics.DrawLine(SystemPens.ControlLight, canvasBounds.Left, canvasBounds.Top, canvasBounds.Right, canvasBounds.Top)
                    graphics.FillRectangle(designerTheme.PreviewBackgroundBrush, canvasBounds)
                End If
                If (Me.PreviewDesigner Is Nothing) Then
                    Dim boundingRect As Rectangle = Me.canvasBounds
                    boundingRect.Inflate(-margin.Width, -margin.Height)
                    Dim text As String = DR.GetString("SelectActivityDesc", New Object(0  - 1) {})
                    ActivityDesignerPaint.DrawText(graphics, designerTheme.Font, [text], boundingRect, StringAlignment.Center, WorkflowTheme.CurrentTheme.AmbientTheme.TextQuality, designerTheme.ForegroundBrush)
                End If
                If Me.PreviewMode Then
                    Dim image2 As Image = Me.GeneratePreview(graphics)
                    If (Not image2 Is Nothing) Then
                        Dim empty As Rectangle = Rectangle.Empty
                        Dim size2 As New Size((Me.canvasBounds.Width - (2 * margin.Width)), (Me.canvasBounds.Height - (2 * margin.Height)))
                        Dim num As Double = (CDbl(image2.Width) / CDbl(size2.Width))
                        num = Math.Max(Math.Max(num, (CDbl(image2.Height) / CDbl(size2.Height))), 1.2999999523162842)
                        empty.Width = Convert.ToInt32(Math.Ceiling(CDbl((CDbl(image2.Width) / num))))
                        empty.Height = Convert.ToInt32(Math.Ceiling(CDbl((CDbl(image2.Height) / num))))
                        empty.X = ((Me.canvasBounds.Left + (Me.canvasBounds.Width / 2)) - (empty.Width / 2))
                        empty.Y = ((Me.canvasBounds.Top + (Me.canvasBounds.Height / 2)) - (empty.Height / 2))
                        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic
                        graphics.DrawImage(image2, empty, New Rectangle(Point.Empty, image2.Size), GraphicsUnit.Pixel)
                    End If
                    Dim destination As Rectangle = Me.canvasBounds
                    destination.Inflate(-margin.Width, -margin.Height)
                    ActivityDesignerPaint.DrawImage(graphics, ActivityPreviewDesignerTheme.PreviewImage, destination, DesignerContentAlignment.TopLeft)
                ElseIf (Not Me.PreviewDesigner Is Nothing) Then
                    Dim bounds As Rectangle = Me.PreviewDesigner.Bounds
                    bounds.Inflate(margin.Width, margin.Height)
                    DirectCast(Me.PreviewDesigner, IWorkflowDesignerMessageSink).OnPaint(New PaintEventArgs(graphics, bounds), bounds)
                End If
            End If
        End Sub

        Private Sub EnsureValidDesignerPreview(ByVal designer As ActivityDesigner)
            Dim designer2 As CompositeActivityDesigner = [TryCast](designer,CompositeActivityDesigner)
            If ((Not designer2 Is Nothing) AndAlso designer2.Expanded) Then
                Dim designerTheme As ActivityPreviewDesignerTheme = [TryCast](Me.parentDesigner.DesignerTheme,ActivityPreviewDesignerTheme)
                If (Not designerTheme Is Nothing) Then
                    Dim previewWindowSize As Size = designerTheme.PreviewWindowSize
                    Dim size As Size = designer2.Size
                    Dim num As Single = (CSng(previewWindowSize.Width) / CSng(size.Width))
                    If (Math.Min(num, (CSng(previewWindowSize.Height) / CSng(size.Height))) < 0.1!) Then
                        If (Not designer2.CanExpandCollapse AndAlso (designer2.ContainedDesigners.Count > 0)) Then
                            designer2 = [TryCast](designer2.ContainedDesigners.Item(0),CompositeActivityDesigner)
                        End If
                        If (Not designer2 Is Nothing) Then
                            designer2.Expanded = False
                        End If
                    End If
                End If
            End If
        End Sub

        Private Function GeneratePreview(ByVal graphics As Graphics) As Image
            If (Me.previewedActivityImage Is Nothing) Then
                Dim previewDesigner As ActivityDesigner = Me.PreviewDesigner
                If ((Not previewDesigner Is Nothing) AndAlso (Not Me.parentDesigner Is Nothing)) Then
                    Me.previewedActivityImage = previewDesigner.GetPreviewImage(graphics)
                End If
            End If
            Return Me.previewedActivityImage
        End Function

        Public Sub OnLayoutSize(ByVal graphics As Graphics, ByVal minWidth As Integer)
            Dim designerTheme As ActivityPreviewDesignerTheme = [TryCast](Me.parentDesigner.DesignerTheme,ActivityPreviewDesignerTheme)
            If (Not designerTheme Is Nothing) Then
                Dim margin As Size = WorkflowTheme.CurrentTheme.AmbientTheme.Margin
                If (Not Me.PreviewMode AndAlso (Not Me.PreviewDesigner Is Nothing)) Then
                    Me.canvasBounds.Size = Me.PreviewDesigner.Bounds.Size
                    Me.canvasBounds.Inflate((margin.Width * 2), (margin.Height * 2))
                    Me.canvasBounds.Size = New Size(Math.Max(Me.canvasBounds.Width, designerTheme.PreviewWindowSize.Width), Math.Max(Me.canvasBounds.Height, designerTheme.PreviewWindowSize.Height))
                Else
                    Me.canvasBounds.Size = designerTheme.PreviewWindowSize
                End If
                Me.canvasBounds.Width = Math.Max(Me.canvasBounds.Width, minWidth)
                Dim ef As SizeF = graphics.MeasureString(Me.PreviewModeDescription, designerTheme.Font)
                Me.previewDescTextSize = New Size(Convert.ToInt32(Math.Ceiling(CDbl(ef.Width))), Convert.ToInt32(Math.Ceiling(CDbl(ef.Height))))
                Me.previewDescTextSize.Width = Math.Min(((Me.canvasBounds.Size.Width - margin.Width) - Me.previewModeButtonRectangle.Size.Width), Me.previewDescTextSize.Width)
                Me.previewModeDescRectangle.Size = Me.previewDescTextSize
                Me.previewModeButtonRectangle.Height = Math.Min(designerTheme.PreviewButtonSize.Height, Me.previewDescTextSize.Height)
                Me.previewModeButtonRectangle.Width = Me.previewModeButtonRectangle.Size.Height
                Dim empty As Size = Size.Empty
                empty.Width = (Me.canvasBounds.Width + (2 * margin.Width))
                empty.Height = Math.Max(Me.previewModeButtonRectangle.Size.Height, Me.previewDescTextSize.Height)
                empty.Height = (empty.Height + margin.Height)
                empty.Height = (empty.Height + Me.canvasBounds.Height)
                Me.bounds.Size = empty
            End If
        End Sub

        Public Sub OnMouseDown(ByVal e As MouseEventArgs)
            If Me.PreviewModeButtonRectangle.Contains(New Point(e.X, e.Y)) Then
                Me.PreviewMode = Not Me.PreviewMode
            End If
        End Sub

        Public Sub Refresh()
            If (Not Me.previewedActivityImage Is Nothing) Then
                Me.previewedActivityImage.Dispose
                Me.previewedActivityImage = Nothing
            End If
            If (Not Me.serviceProvider Is Nothing) Then
                Dim service As WorkflowView = [TryCast](Me.serviceProvider.GetService(GetType(WorkflowView)),WorkflowView)
                If (Not service Is Nothing) Then
                    service.InvalidateLogicalRectangle(Me.bounds)
                End If
            End If
        End Sub


        ' Properties
        Public ReadOnly Property AccessibilityObject As AccessibleObject
            Get
                If (Me.accessibilityObject Is Nothing) Then
                    Me.accessibilityObject = New PreviewWindowAccessibleObject(Me)
                End If
                Return Me.accessibilityObject
            End Get
        End Property

        Public ReadOnly Property Bounds As Rectangle
            Get
                Return Me.bounds
            End Get
        End Property

        Public Property Location As Point
            Get
                Return Me.bounds.Location
            End Get
            Set(ByVal value As Point)
                Dim margin As Size = WorkflowTheme.CurrentTheme.AmbientTheme.Margin
                Me.bounds.Location = value
                Dim num As Integer = Math.Max(Me.previewModeDescRectangle.Height, Me.previewModeButtonRectangle.Height)
                Dim empty As Point = Point.Empty
                empty.X = ((((Me.bounds.Left + (Me.bounds.Width / 2)) - (Me.previewModeDescRectangle.Width / 2)) + Me.previewModeButtonRectangle.Width) + margin.Width)
                empty.Y = ((Me.bounds.Top + (num / 2)) - (Me.previewModeDescRectangle.Height / 2))
                Me.previewModeDescRectangle.Location = empty
                Dim point2 As Point = Point.Empty
                point2.X = (empty.X - (Me.previewModeButtonRectangle.Width + margin.Width))
                point2.Y = ((Me.bounds.Top + (num / 2)) - (Me.previewModeButtonRectangle.Height / 2))
                Me.previewModeButtonRectangle.Location = point2
                Me.canvasBounds.Location = New Point(((value.X + (Me.bounds.Width / 2)) - (Me.canvasBounds.Width / 2)), (Me.previewModeDescRectangle.Bottom + margin.Height))
                If (Not Me.PreviewDesigner Is Nothing) Then
                    Dim point3 As Point = Point.Empty
                    point3.X = ((Me.canvasBounds.Left + (Me.canvasBounds.Width / 2)) - (Me.PreviewDesigner.Size.Width / 2))
                    point3.Y = ((Me.canvasBounds.Top + (Me.canvasBounds.Height / 2)) - (Me.PreviewDesigner.Size.Height / 2))
                    Me.PreviewDesigner.Location = point3
                End If
            End Set
        End Property

        Private ReadOnly Property PreviewDesigner As ActivityDesigner
            Get
                Return ActivityDesigner.GetDesigner(Me.previewedActivity)
            End Get
        End Property

        Public Property PreviewedActivity As Activity
            Get
                Return Me.previewedActivity
            End Get
            Set(ByVal value As Activity)
                If (Not Me.previewedActivity Is value) Then
                    Me.previewedActivity = value
                    If (Not Me.previewedActivityImage Is Nothing) Then
                        Me.previewedActivityImage.Dispose
                        Me.previewedActivityImage = Nothing
                    End If
                    If (Not Me.serviceProvider Is Nothing) Then
                        Dim service As WorkflowView = [TryCast](Me.serviceProvider.GetService(GetType(WorkflowView)),WorkflowView)
                        If (Not service Is Nothing) Then
                            service.PerformLayout(False)
                        End If
                    End If
                End If
            End Set
        End Property

        Public Property PreviewMode As Boolean
            Get
                Return Me.previewMode
            End Get
            Set(ByVal value As Boolean)
                If (Me.previewMode <> value) Then
                    Me.previewMode = value
                    If Me.previewMode Then
                        Me.EnsureValidDesignerPreview(Me.PreviewDesigner)
                        If (Not Me.previewedActivityImage Is Nothing) Then
                            Me.previewedActivityImage.Dispose
                            Me.previewedActivityImage = Nothing
                        End If
                    End If
                    If (Not Me.PreviewModeChanged Is Nothing) Then
                        Me.PreviewModeChanged.Invoke(Me, EventArgs.Empty)
                    End If
                    If (Not Me.serviceProvider Is Nothing) Then
                        Dim service As WorkflowView = [TryCast](Me.serviceProvider.GetService(GetType(WorkflowView)),WorkflowView)
                        If (Not service Is Nothing) Then
                            service.PerformLayout(False)
                        End If
                    End If
                End If
            End Set
        End Property

        Private ReadOnly Property PreviewModeButtonRectangle As Rectangle
            Get
                Return Me.previewModeButtonRectangle
            End Get
        End Property

        Private ReadOnly Property PreviewModeDescription As String
            Get
                Dim str As String = If(Me.PreviewMode, DR.GetString("PreviewMode", New Object(0  - 1) {}), DR.GetString("EditMode", New Object(0  - 1) {}))
                Dim activity As CompositeActivity = If((Not Me.parentDesigner Is Nothing), [TryCast](Me.parentDesigner.Activity,CompositeActivity), Nothing)
                If (activity Is Nothing) Then
                    Return str
                End If
                Dim component As IComponent = If((Not Me.PreviewDesigner Is Nothing), Me.PreviewDesigner.Activity, Nothing)
                If (component Is Nothing) Then
                    Return str
                End If
                Dim list As New List([Of] Activity)
                Dim activity2 As Activity
                For Each activity2 In activity.Activities
                    If Not Helpers.IsAlternateFlowActivity(activity2) Then
                        list.Add(activity2)
                    End If
                Next
                Dim num As Integer = (list.IndexOf([TryCast](component,Activity)) + 1)
                Dim str2 As String = str
                Return String.Concat(New String() { str2, " [", num.ToString(CultureInfo.CurrentCulture), "/", list.Count.ToString(CultureInfo.CurrentCulture), "]" })
            End Get
        End Property

        Public ReadOnly Property Size As Size
            Get
                Return Me.bounds.Size
            End Get
        End Property


        ' Fields
        Private accessibilityObject As PreviewWindowAccessibleObject
        Private bounds As Rectangle = Rectangle.Empty
        Private canvasBounds As Rectangle = Rectangle.Empty
        Private parentDesigner As ActivityPreviewDesigner
        Private previewDescTextSize As Size = Size.Empty
        Private previewedActivity As Activity
        Private previewedActivityImage As Image
        Private previewMode As Boolean = True
        Private previewModeButtonRectangle As Rectangle = Rectangle.Empty
        Private previewModeDescRectangle As Rectangle = Rectangle.Empty
        Private serviceProvider As IServiceProvider

        ' Nested Types
        Private NotInheritable Class PreviewWindowAccessibleObject
            Inherits AccessibleObject
            ' Methods
            Friend Sub New(ByVal previewWindow As PreviewWindow)
                Me.previewWindow = previewWindow
            End Sub

            Public Overrides Sub DoDefaultAction()
                Me.previewWindow.PreviewMode = Not Me.previewWindow.PreviewMode
            End Sub

            Public Overrides Function Navigate(ByVal navdir As AccessibleNavigation) As AccessibleObject
                If (navdir = AccessibleNavigation.Previous) Then
                    Dim childCount As Integer = Me.previewWindow.parentDesigner.AccessibilityObject.GetChildCount
                    If ((childCount - 3) >= 0) Then
                        Return Me.previewWindow.parentDesigner.AccessibilityObject.GetChild((childCount - 3))
                    End If
                ElseIf (navdir = AccessibleNavigation.Next) Then
                    If Me.previewWindow.PreviewMode Then
                        Return Me.previewWindow.parentDesigner.AccessibilityObject.Navigate(navdir)
                    End If
                    Dim num2 As Integer = Me.previewWindow.parentDesigner.AccessibilityObject.GetChildCount
                    If ((num2 - 1) >= 0) Then
                        Return Me.previewWindow.parentDesigner.AccessibilityObject.GetChild((num2 - 1))
                    End If
                End If
                Return MyBase.Navigate(navdir)
            End Function

            Public Overrides Sub [Select](ByVal flags As AccessibleSelection)
                MyBase.Select(flags)
            End Sub


            ' Properties
            Public Overrides ReadOnly Property Bounds As Rectangle
                Get
                    Dim previewModeButtonRectangle As Rectangle = Me.previewWindow.PreviewModeButtonRectangle
                    Dim service As WorkflowView = [TryCast](Me.previewWindow.serviceProvider.GetService(GetType(WorkflowView)),WorkflowView)
                    If (Not service Is Nothing) Then
                        previewModeButtonRectangle = New Rectangle(service.LogicalPointToScreen(previewModeButtonRectangle.Location), service.LogicalSizeToClient(previewModeButtonRectangle.Size))
                    End If
                    Return previewModeButtonRectangle
                End Get
            End Property

            Public Overrides ReadOnly Property DefaultAction As String
                Get
                    Return DR.GetString("AccessibleAction", New Object(0  - 1) {})
                End Get
            End Property

            Public Overrides ReadOnly Property Description As String
                Get
                    Return DR.GetString("PreviewButtonAccessibleDescription", New Object(0  - 1) {})
                End Get
            End Property

            Public Overrides ReadOnly Property Help As String
                Get
                    Return DR.GetString("PreviewButtonAccessibleHelp", New Object(0  - 1) {})
                End Get
            End Property

            Public Overrides Property Name As String
                Get
                    Return DR.GetString("PreviewButtonName", New Object(0  - 1) {})
                End Get
                Set(ByVal value As String)
                End Set
            End Property

            Public Overrides ReadOnly Property Parent As AccessibleObject
                Get
                    Return Me.previewWindow.parentDesigner.AccessibilityObject
                End Get
            End Property

            Public Overrides ReadOnly Property Role As AccessibleRole
                Get
                    Return AccessibleRole.Diagram
                End Get
            End Property

            Public Overrides ReadOnly Property State As AccessibleStates
                Get
                    Return MyBase.State
                End Get
            End Property


            ' Fields
            Private previewWindow As PreviewWindow
        End Class
    End Class
End Namespace

